package org.xiaojl.xcloud.tools.gateway.fallback;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;
import org.xiaojl.xcloud.tools.gateway.RpcResult;
import org.xiaojl.xcloud.tools.gateway.kit.JsonKit;

import com.netflix.zuul.context.RequestContext;

/**  
 * <p>Title: XcloudRouteFallbackProvider</p>  
 *
 * <p>Description: 熔断处理器</p>  
 *
 * @author jilong.xiao  
 * @date 2018年5月7日  
 */
@Component
public class XcloudRouteFallbackProvider implements ZuulFallbackProvider {
	private static final Logger log = LoggerFactory.getLogger(XcloudRouteFallbackProvider.class);
	
	@Override
	public String getRoute() {
		/**
		 * 定义开启熔断功能的微服务的服务名称，必须是Eureka中注册的，全部用*
		 */
		return "*";
	}

	@Override
	public ClientHttpResponse fallbackResponse() {
		//设置响应信息
		return new ClientHttpResponse(){
			@Override
			public InputStream getBody() throws IOException {
				RequestContext rc = RequestContext.getCurrentContext();
				Object serviceId = rc.get("serviceId");
				Throwable e = rc.getThrowable();
				if(e != null){
					log.error("[熔断处理]：["+serviceId+"]服务不可用，异常信息：",e);
				}else{
					if(log.isDebugEnabled()){
						log.debug("[熔断处理]：["+serviceId+"]服务不可用");
					}
				}
				RpcResult result = RpcResult.fail("服务不可用", "熔断机制触发响应", e==null?"":e.getLocalizedMessage());
				return new ByteArrayInputStream(JsonKit.toJson(result).getBytes());
			}

			@Override
			public HttpHeaders getHeaders() {
				HttpHeaders headers = new HttpHeaders();
//				MediaType mt = new MediaType("application", "json", Charset.forName("UTF-8"));
				headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
				return headers;
			}

			@Override
			public HttpStatus getStatusCode() throws IOException {
				//503
				return HttpStatus.SERVICE_UNAVAILABLE;
			}

			@Override
			public int getRawStatusCode() throws IOException {
				return getStatusCode().value();
			}

			@Override
			public String getStatusText() throws IOException {
				return getStatusCode().getReasonPhrase();
			}

			@Override
			public void close() {
				
			}
		};
	}

}
